<template>
  <form class="page page-office2images">
    <h4 class="text-center">提取Office文件中的图片</h4>
    <div class="alert alert-info">
      本工具只支持docx、pptx、xlsx文件。
    </div>
    <div class="fieldset-options">
      <fieldset>
        <legend>操作设置</legend>
        <div class="form-group row-flex" align="center">
          <div class="row-flex-prefix">输出目录</div>
          <div class="row-flex-main"><input class="form-control" type="text" v-model="toPath" /></div>
          <div class="row-flex-suffix"><x-button @click="setToPath">选择...</x-button></div>
        </div>
      </fieldset>
    </div>
    <fieldset class="fieldset-content">
      <legend>文件列表</legend>
      <div class="row-flex" align="center">
        <div class="row-flex-main text-left">共 {{filesList.length}} 个文件</div>
        <div class="row-flex-suffix">
          <button type="button" class="btn btn-link" @click="execute" :disabled="loadingCount > 0">开始处理</button>
          <button type="button" class="btn btn-link" @click="clearFilesList">清空</button>
        </div>
      </div>
      <div class="table-header" :style="thStyles">
        <table>
          <tbody>
            <tr>
              <th v-for="(v,i) in tableHeaders" :key="`th_${i}`" :style="{width: v.width}">{{v.label}}</th>
            </tr>
          </tbody>
        </table>
      </div>
      <div class="table-body" @drop.prevent="filesDrop" @dragover.prevent>
        <table ref="table">
          <tbody>
            <tr v-for="(v,i) in filesList" :key="`file_${i}`">
              <template v-for="(item,index) in tableHeaders">
                <td :style="{width: item.width}" :key="`td_${i}_${index}`">
                  <button v-if="item.value==='action'" type="button" class="btn btn-link" @click="deleteFileItem(i)" title="删除">
                    <i class="fa fa-close"></i>
                  </button>
                  <span v-else-if="item.value==='index'">{{i + 1}}</span>
                  <span v-else>{{v[item.value] || ''}}</span>
                </td>
              </template>
            </tr>
            <tr v-if="filesList.length===0" class="nodata-tr"><td>将待处理的文件拖动到此处</td></tr>
          </tbody>
        </table>
      </div>
    </fieldset>
  </form>
</template>

<script>
const fs = global.require('fs')
const path = global.require('path')
const {remote} = global.require('electron')
const {dialog} = remote
const selfWindow= remote.getCurrentWindow()
let JSZip = global.JSZip || null

export default {
  name: 'office2images',
  data () {
    return {
      toPath: this.$sharedObject('desktopPath'),
      filesList: [],
      tableHeaders: [
        {label: '序号', value: 'index', width: '10%'},
        {label: '文件路径', value: 'path', width: '50%'},
        {label: '状态', value: 'status', width: '20%'},
        {label: '操作', value: 'action', width: '20%'},
      ],
      thStyles: {},
      loadingCount: 0
    }
  },
  computed: {
    filePathsList () {
      return this.filesList.map(v => v.path)
    }
  },
  methods: {
    // 设置保存位置
    setToPath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择目录',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openDirectory']
      })
      console.log(filePaths)
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.toPath = filePaths[0]
      }
    },
    // 拖拽待处理文件
    filesDrop (e) {
      const filesList = e.dataTransfer.files
      if (!filesList) return
      for (let i = 0; i < filesList.length; i++) {
        const file = filesList[i]
				let label = file.name || path.basename(file.path)
				if (!/.(xlsx|docx|pptx)$/i.test(label)) {
					continue
				}
        if (!this.filePathsList.includes(file.path)) {
          this.filesList.push({
            name: label,
            path: file.path,
            status: '',
          })
        }
      }
      this.checkScroll()
    },
    // 删除条目
    deleteFileItem (index) {
      this.filesList.splice(index, 1)
      this.checkScroll()
    },
    checkScroll () {
      this.$nextTick(() => {
        if (!this.$refs.table) return
        let tableHeight = this.$refs.table.clientHeight
        let tableParentHeight = this.$refs.table.parentNode.clientHeight
        if (tableHeight > tableParentHeight) {
          this.thStyles = {overflow: 'hidden scroll'}
        } else {
          this.thStyles = {overflow: 'hidden'}
        }
      })
    },
    // 清空待处理文件
    clearFilesList () {
      this.filesList = []
      this.thStyles = {}
      this.loadingCount = 0
    },
    // 执行处理
    execute () {
      this.filesList.forEach((v, i) => {
        this.loadingCount++
        this.$set(this.filesList[i], 'status', '处理中')
        this.executeItem(v, i).then(() => {
          this.$set(this.filesList[i], 'status', '处理成功')
        }).catch(() => {
          this.$set(this.filesList[i], 'status', '处理失败')
        }).finally(() => {
          this.loadingCount--
        })
      })
    },
    // 处理单个文件
    executeItem (officeFile, index) {
      let zip = new JSZip()
      let bytes = fs.readFileSync(officeFile.path)
      let dirPath = path.join(this.toPath, officeFile.name || `${Date.now()}_${index}`)
      if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, {recursive: true})
      }
      return zip.loadAsync(bytes).then(() => {
        // 将数据写入本地文件
        let arr = []
        zip.forEach((relativePath, file) => {
          if (relativePath.indexOf('ppt/media') === 0 ||relativePath.indexOf('xl/media') === 0 ||relativePath.indexOf('word/media') === 0) {
            console.log('relativePath:', relativePath)
            arr.push(file.async('nodebuffer').then((content) => {
              if (!file.dir) {
                let filename = path.basename(relativePath)
                let filepath = path.resolve(dirPath, filename)
                fs.writeFileSync(filepath, content)
              }
            }))
          }
        })
        return Promise.all(arr)
      })
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.page-office2images {
	display: flex;
	flex-direction: column;
  .row-flex-prefix {
    text-align: left;
  }
  .form-group + .form-group {
    margin-top: .5em;
  }
  fieldset {
    .row-flex-prefix {width: 5em;}
  }
	.fieldset-content {
		height: 0;
		flex-grow: 1;
    margin-top: .5em;
    .table-header,
    .table-body {
      table {
        width: 100%;
        border: 1px solid @borderGrey;
        tr {height: 2em;}
        th, td {
          border: 1px solid @borderGrey;
          text-align: center;
          vertical-align: middle;
        }
        .nodata-tr {
          height: 100%;
          font-size: 16px;
          color: #999;
        }
      }
    }
    .table-body {
      height: calc(100% - 6.5em);
      overflow: auto;
      table {
        min-height: 100%;
      }
    }
  }
  .fieldset-options {
    fieldset {
      height: 100%;
    }
  }
}
</style>
